﻿// QuocPT
 
package com.bit101.components
{
	import flash.display.DisplayObjectContainer;
	import flash.events.MouseEvent;
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.display.Graphics;
	import flash.display.BitmapData;
	import flash.display.IBitmapDrawable;
	import flash.geom.Rectangle;
	import flash.display.Bitmap;

	public class ImageButton extends Component
	{
		protected var _face : BitmapData;
		protected var _faceContainer : Bitmap;
		protected var _upSkin:DisplayObject;
		protected var _overSkin:DisplayObject;
		protected var _downSkin:DisplayObject;
		protected var _disableSkin:DisplayObject;
		protected var _isMouseDown:Boolean	=	false;
		protected var _isMouseOver:Boolean	=	false;
		
		protected var _centerAlign : Boolean	=	true;
		
		/**
		 * Constructor
		 * @param parent The parent DisplayObjectContainer on which to add this PushButton.
		 * @param xpos The x position to place this component.
		 * @param ypos The y position to place this component.
		 * @param label The string to use for the initial label of this component.
 		 * @param defaultHandler The event handling function to handle the default event for this component (click in this case).
		 */
		public function ImageButton( upSkin:DisplayObject, 
									overSkin:DisplayObject = null, downSkin:DisplayObject = null, disableSkin:DisplayObject = null,
									parent:DisplayObjectContainer = null, 
									xpos:Number = 0, ypos:Number =  0, 
									defaultHandler:Function = null)
		{			
			this._upSkin			=	upSkin;
						
			if( overSkin )
				this._overSkin		=	overSkin;
			else
				this._overSkin		=	this._upSkin;
				
			if( downSkin )
				this._downSkin		=	downSkin;
			else
				this._downSkin		=	this._upSkin;
			
			if( disableSkin )
				this._disableSkin	=	disableSkin;
			else
				this._disableSkin	=	this._upSkin;			
			
			if(defaultHandler != null)
			{
				addEventListener(MouseEvent.CLICK, defaultHandler);
			}
				
			super(parent, xpos, ypos);
		}
		
		/**
		 * Initializes the component.
		 */
		override protected function init():void
		{
			super.init();
			buttonMode 		=	true;
			useHandCursor 	=	true;
			mouseChildren	=	false;					
		}		
		
		/**
		 * Creates and adds the child display objects of this component.
		 */
		override protected function addChildren():void
		{						
			_faceContainer	=	new Bitmap();			
			addChild( _faceContainer );
			
			invalidateSize();
			
			drawFace( _upSkin );
			
			addEventListener(MouseEvent.MOUSE_DOWN, onMouseGoDown);
			addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
		}
		
		override public function setSize(w:Number, h:Number):void
		{
			invalidateSize();
			super.setSize( w, h );
		}
		
		protected function invalidateSize() : void
		{
			if( _upSkin )
			{
				if( _width < _upSkin.width ) _width		=	_upSkin.width;
				if( _height < _upSkin.width ) _height	=	_upSkin.height;
			}
			
			if( _overSkin )
			{
				if( _width < _overSkin.width ) _width	=	_overSkin.width;
				if( _height < _overSkin.width ) _height	=	_overSkin.height;
			}
			
			if( _downSkin )
			{
				if( _width < _downSkin.width ) _width	=	_downSkin.width;
				if( _height < _downSkin.width ) _height	=	_downSkin.height;
			}
			
			if( _disableSkin )
			{
				if( _width < _disableSkin.width ) _width	=	_disableSkin.width;
				if( _height < _disableSkin.width ) _height	=	_disableSkin.height;
			}
			
			_face	=	new BitmapData( _width, _height );
			_faceContainer.bitmapData	=	_face;
		}
				
		protected function drawFace( src : IBitmapDrawable ) : void
		{
			_face.fillRect( new Rectangle( 0, 0, _face.width, _face.height ), 0 );
			_face.draw( src );			
			
			if( _centerAlign )
			{
				var offX : Number	=	0;
				var offY : Number	=	0;
				
				if( src == _upSkin )
				{
					offX	=	- _upSkin.width * 0.5;
					offY	=	- _upSkin.height * 0.5;
				}
				else if( src == _downSkin )
				{
					offX	=	- _downSkin.width * 0.5;
					offY	=	- _downSkin.height * 0.5;
				}
				else if( src == _overSkin )
				{
					offX	=	- _overSkin.width * 0.5;
					offY	=	- _overSkin.height * 0.5;
				}
				else
				{
					offX	=	- _disableSkin.width * 0.5;
					offY	=	- _disableSkin.height * 0.5;
				}
				
				_faceContainer.x	=	offX;
				_faceContainer.y	=	offY;				
			}
		}
		
		///////////////////////////////////
		// event handlers
		///////////////////////////////////
		
		override public function set enabled(value:Boolean):void
		{
			super.enabled = value;
			
			if( value )
				drawFace( _disableSkin );
			else
				drawFace( _upSkin );
		}
		
		/**
		 * Internal mouseOver handler.
		 * @param event The MouseEvent passed by the system.
		 */
		protected function onMouseOver(event:MouseEvent):void
		{			
			drawFace( _overSkin );
			
			_isMouseOver	=	true;
			
			addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
		}
		
		/**
		 * Internal mouseOut handler.
		 * @param event The MouseEvent passed by the system.
		 */
		protected function onMouseOut(event:MouseEvent):void
		{
			if( ! _isMouseDown )
				drawFace( _upSkin );
				
				
			_isMouseOver	=	false;
			
			removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
		}
		
		/**
		 * Internal mouseOut handler.
		 * @param event The MouseEvent passed by the system.
		 */
		protected function onMouseGoDown(event:MouseEvent):void
		{					
			drawFace( _downSkin );
			
			_isMouseDown	=	true;
			
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseGoUp);
		}
		
		/**
		 * Internal mouseUp handler.
		 * @param event The MouseEvent passed by the system.
		 */
		protected function onMouseGoUp(event:MouseEvent):void
		{
			if( _isMouseOver )
				drawFace( _overSkin );
			else
				drawFace( _upSkin );
			
			_isMouseDown	=	false;
			
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseGoUp);
		}
		
		public function set centerAlign( val : Boolean ) : void
		{
			_centerAlign = val;
		}
		
		public function get centerAlign() : Boolean
		{
			return _centerAlign;
		}
	}
}